// 封装axios请求
import axios from 'axios'
// 引入错误弹窗
import { Message } from 'element-ui'
import store from '@/store'
import router from '@/router'
// axios.create：创建一个自定义的axios实例
// 该service实例等同于之前的axios,只是这里添加了一些特殊配置
const service = axios.create({
  // baseURL：基地址
  // 请求的地址会与基地址自动拼接 = baseURL + url

  // process.env 是nodejs内置的固定环境变量对象
  // npm run dev -〉启动开发服务，项目根目录.env.development环境变量配置文件里值添加到process.env对象上
  // npm - run- build:prod:->·启动打包，项目根目录·.env.production环境变量配置文件里值添加到process.env对象上
  // 问题:为何不直接写在这里?
  // 答案:
  // 开发的时候，用的是基地址1上线的时候，用的是基地址2、
  baseURL: process.env.VUE_APP_BASE_API,
  // 设置超时事件，ms
  timeout: 5000
})

// 设置请求拦截器
// views逻辑页面中 ->调用api里的接口方法 -> request.js中的service(axios方法) -> 再执行请求拦截器
service.interceptors.request.use(
  // 参数1：箭头函数体 -> 发起请求之前会走这里(必须return 请求配置对象，return到axios的use内)
  config => {
    const token = store.getters.token // 获取token
    // 如果token存在,将token设置在请求头上
    if (token) {
      config.headers.Authorization = `Bearer ${token}`
    }
    return config
  },
  // 参数2：箭头函数体 -> 在发起请求前，axios内有报错，会直接进入error函数体内
  error => {
    return Promise.reject(error)
  }
)

// 设置响应拦截器
service.interceptors.response.use(
  // 参数1：箭头函数体 -> (成功)只有在响应状态码为2xx,3xx时，进入参数1
  response => {
    // 判断状态码，200表示可以正常访问接口
    const { success, message } = response.data
    // 判断请求后的登录状态
    if (success) {
      return response.data // 返回的是后台返回的页面,axios返回的数据会将后台的数据保存到data中,所以前端在取出数据时,需要进行.data.data,这里这样处理是为了简化
    } else {
      // 弹出提示框
      Message.error(message)
      return Promise.reject(message)
    }
  },
  // 参数2：箭头函数体 -> (失败)只有在响应状态码为4xx,5xx(或者捕获到了其他错误)时，进入
  error => {
    // axios()函数原地，那个promise对象接受到了失败的状态
    // 4xx响应状态弹出框
    // &&是为了防止 null.data
    Message.error((error.response && error.response.data && error.response.data.message) || error.message)
    // 如果响应状态码是10002
    if (error.response && error.response.data && error.response.data.code === 10002) {
      // 清除token，清除state中的所有数据，并跳转到登录页面
      store.dispatch('user/logoutActions')
      // 被动退出
      router.replace(`/login?redirect=${router.currentRoute.fullPath}`)
    }
    return Promise.reject(error)
  }
)

export default service
